package com.genius.controller;

import com.genius.annotation.PreFuncAuth;
import com.genius.core.JSONResult;
import com.genius.utils.PageUtils;
import com.genius.utils.SecurityUtils;
import com.genius.workflow.bo.SelectInstanceByPageBO;
import com.genius.workflow.bo.StartInstanceBO;
import com.genius.workflow.bo.SuspendInstanceBO;
import com.genius.workflow.vo.ProcessInstanceVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.flowable.common.engine.impl.identity.Authentication;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.ProcessInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("processInstance")
@Api(value = "流程实例接口", tags = {"用于流程实例的接口"})
public class InstanceController {

    @Autowired
    private RepositoryService repositoryService;

    @Autowired
    private RuntimeService runtimeService;

    @PostMapping("/selectInstanceByPage")
    @ApiOperation(value = "流程实例（分页查询）",notes = "查询流程实例分页数据", httpMethod = "POST")
    @PreFuncAuth("PROCESS:INSTANCE:SELECT")
    public JSONResult selectInstanceByPage(@Valid @RequestBody SelectInstanceByPageBO selectInstanceByPageBO){
        Integer pageNum = selectInstanceByPageBO.getPageNum();
        Integer pageSize = selectInstanceByPageBO.getPageSize();
        int firstResult = pageNum*pageSize-pageSize;
        int maxResult = pageNum*pageSize-1;
        List<ProcessInstance> processInstanceList = runtimeService.createProcessInstanceQuery().listPage(firstResult,maxResult);
        processInstanceList.sort((x,y)->y.getStartTime().toString().compareTo(x.getStartTime().toString()));
        List<ProcessInstanceVO> processInstanceVOList = new ArrayList<>();
        for(ProcessInstance processInstance : processInstanceList){
            ProcessInstanceVO processInstanceVO = new ProcessInstanceVO();
            processInstanceVO.setId(processInstance.getId());
            processInstanceVO.setName(processInstance.getName());
            processInstanceVO.setStatus(processInstance.isSuspended());
            processInstanceVO.setDefinitionId(processInstance.getProcessDefinitionId());
            processInstanceVO.setDefinitionKey(processInstance.getProcessDefinitionKey());
            processInstanceVO.setStartDate(processInstance.getStartTime());
            processInstanceVO.setDefinitionVersion(processInstance.getProcessDefinitionVersion());
            ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                    .processDefinitionId(processInstance.getProcessDefinitionId())
                    .singleResult();
            processInstanceVO.setDeploymentId(processDefinition.getDeploymentId());
            processInstanceVO.setResourceName(processInstanceVO.getResourceName());
            processInstanceVOList.add(processInstanceVO);
        }
        Map<String,Object> result = PageUtils.getResultTableData(processInstanceVOList);
        return JSONResult.ok(result);
    }

    @PostMapping("/startInstance")
    @ApiOperation(value = "启动流程实例",notes = "启动流程实例", httpMethod = "POST")
    @PreFuncAuth("PROCESS:INSTANCE:START")
    public JSONResult startInstance(@Valid @RequestBody StartInstanceBO startInstanceBO){
        Authentication.setAuthenticatedUserId(SecurityUtils.getUsername());
        Map<String, Object> variables = new HashMap<>();
        variables.put("applyUser", SecurityUtils.getUsername());
        ProcessInstance processInstance = runtimeService.createProcessInstanceBuilder()
                .processDefinitionKey(startInstanceBO.getDefinitionKey())
                .name(startInstanceBO.getInstanceName())
                .businessKey(startInstanceBO.getBusinessKey())
                .businessStatus("10")
                .variables(variables)
                .start();
        return JSONResult.ok("启动"+processInstance.getName()+"成功");
    }

    @PostMapping("/suspendInstance")
    @ApiOperation(value = "挂起流程实例",notes = "挂起流程实例", httpMethod = "POST")
    @PreFuncAuth("PROCESS:INSTANCE:SUSPEND")
    public JSONResult suspendInstance(@Valid @RequestBody SuspendInstanceBO suspendInstanceBO){
        runtimeService.suspendProcessInstanceById(suspendInstanceBO.getInstanceId());
        return JSONResult.ok("挂起流程实例成功");
    }

    @PostMapping("/resumeInstance")
    @ApiOperation(value = "激活流程实例",notes = "激活流程实例", httpMethod = "POST")
    @PreFuncAuth("PROCESS:INSTANCE:RESUME")
    public JSONResult resumeInstance(@Valid @RequestBody SuspendInstanceBO suspendInstanceBO){
        runtimeService.activateProcessInstanceById(suspendInstanceBO.getInstanceId());
        return JSONResult.ok("激活流程实例成功");
    }

    @PostMapping("/deleteInstance")
    @ApiOperation(value = "删除流程实例",notes = "删除流程实例", httpMethod = "POST")
    @PreFuncAuth("PROCESS:INSTANCE:DELETE")
    public JSONResult deleteInstance(@Valid @RequestBody SuspendInstanceBO suspendInstanceBO){
        runtimeService.deleteProcessInstance(suspendInstanceBO.getInstanceId(),"");
        return JSONResult.ok("删除流程实例成功");
    }

    @PostMapping("/selectInstanceVariables")
    @ApiOperation(value = "获取流程实例参数",notes = "获取流程实例参数", httpMethod = "POST")
    @PreFuncAuth("PROCESS:INSTANCE:SELECT")
    public JSONResult selectInstanceVariables(@Valid @RequestBody SuspendInstanceBO suspendInstanceBO){
        Map<String, Object> variables = runtimeService.getVariables(suspendInstanceBO.getInstanceId());
        Map<String,Object> result = new HashMap<>();
        result.put("variables",variables);
        return JSONResult.ok(result);
    }
}
